package com.example.completableFutureDemo.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * <pre>
 * 功能描述:自定义线程池
 * https://blog.csdn.net/weixin_42047790/article/details/90698535
 * </pre>
 *
 * @author: 李明杰
 * @date: 2022/1/20 15:15
 */
@Configuration
@EnableAsync
@Slf4j
@Data//无set方法无法注入
@ConfigurationProperties(prefix = "thread-pool")//此处前缀不能写驼峰。下划线和驼峰严格对应
public class AsyncTaskConfig implements AsyncConfigurer {

    /**
     * 最小线程数(核心线程数)
     */
    private int corePoolSize;
    /**
     * 最大线程数
     */
    private int maxPoolSize;
    /**
     * 等待队列(队列最大长度)
     */
    private int queueCapacity;


    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 最小线程数(核心线程数)
        taskExecutor.setCorePoolSize(corePoolSize);
        // 最大线程数
        taskExecutor.setMaxPoolSize(maxPoolSize);
        // 等待队列(队列最大长度)
        taskExecutor.setQueueCapacity(queueCapacity);
        // 拒绝策略
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        taskExecutor.setThreadNamePrefix("diyThreadPool_");

        taskExecutor.initialize();
        return taskExecutor;
    }

    /**
     * 处理返回值为void的异常
     *
     * @return
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> log.error("Exception occurs in async method", ex.getMessage());
    }


}
